﻿using Essensoft.Paylink.WeChatPay.V3.Domain;
using Essensoft.Paylink.WeChatPay.V3.Request;
using Pay.DTO;
using System.Text.Json;

namespace Pay.Services.Imp
{
	/// <summary>
	/// 微信支付V3服务
	/// </summary>
	partial class PayService
	{
		/// <summary>
		/// V3消费者扫二维码支付
		/// </summary>
		private async Task WechatPayV3QRCodeAsync(PayRequestDto payReq, LayuiResultDto<PayResponseDto> result)
		{
			var model = new WeChatPayTransactionsNativeBodyModel
			{
				AppId = _payConfig.AppId,
				MchId = _payConfig.WeChatPayOption.MchId,
				OutTradeNo = payReq.OutTradeNo,
				Description = payReq.Description,
				Amount = new Amount { Total = (int)(payReq.Amount * 100), Currency = "CNY" },
				Attach = payReq.Attach,
				NotifyUrl = payReq.NotifyUrl
			};
			var request = new WeChatPayTransactionsNativeRequest();
			request.SetBodyModel(model);
			var rep = await _weChatPayV3Client.ExecuteAsync(request, _payConfig.WeChatPayOption);
			if (rep.IsError)
			{
				result.Code = 10000;
				result.Msg = $"{rep.Message}|{rep.Detail}";
			}
			else
				result.Data.Result = rep.CodeUrl;
		}

		/// <summary>
		/// V3小程序支付
		/// </summary>
		private async Task WechatPayV3MiniprogramAsync(PayRequestDto payReq, LayuiResultDto<PayResponseDto> result)
		{
			var model = new WeChatPayTransactionsJsApiBodyModel
			{
				AppId = _payConfig.AppId,
				MchId = _payConfig.WeChatPayOption.MchId,
				OutTradeNo = payReq.OutTradeNo,
				Description = payReq.Description,
				Amount = new Amount { Total = (int)(payReq.Amount * 100), Currency = "CNY" },
				Attach = payReq.Attach,
				NotifyUrl = payReq.NotifyUrl,
				Payer = new PayerInfo { OpenId = payReq.OpenId }
			};
			var request = new WeChatPayTransactionsJsApiRequest();
			request.SetBodyModel(model);
			var rep = await _weChatPayV3Client.ExecuteAsync(request, _payConfig.WeChatPayOption);
			if (rep.IsError)
			{
				result.Code = 10000;
				result.Msg = $"{rep.Message}|{rep.Detail}";
			}
			else
			{
				var req = new WeChatPayMiniProgramSdkRequest
				{
					Package = $"prepay_id={rep.PrepayId}"
				};
				var parameter = await _weChatPayV3Client.ExecuteAsync(req, _payConfig.WeChatPayOption);
				// 将参数(parameter)给 小程序前端 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_4.shtml
				result.Data.Result = JsonSerializer.Serialize(parameter);
			}
		}

		/// <summary>
		/// V3公众号支付
		/// </summary>
		private async Task WechatPayV3MPAsync(PayRequestDto payReq, LayuiResultDto<PayResponseDto> result)
		{
			var model = new WeChatPayTransactionsJsApiBodyModel
			{
				AppId = _payConfig.AppId,
				MchId = _payConfig.WeChatPayOption.MchId,
				OutTradeNo = payReq.OutTradeNo,
				Description = payReq.Description,
				Amount = new Amount { Total = (int)(payReq.Amount * 100), Currency = "CNY" },
				Attach = payReq.Attach,
				NotifyUrl = payReq.NotifyUrl,
				Payer = new PayerInfo { OpenId = payReq.OpenId }
			};
			var request = new WeChatPayTransactionsJsApiRequest();
			request.SetBodyModel(model);
			var rep = await _weChatPayV3Client.ExecuteAsync(request, _payConfig.WeChatPayOption);
			if (rep.IsError)
			{
				result.Code = 10000;
				result.Msg = $"{rep.Message}|{rep.Detail}";
			}
			else
			{
				var req = new WeChatPayMiniProgramSdkRequest
				{
					Package = $"prepay_id={rep.PrepayId}"
				};
				var parameter = await _weChatPayV3Client.ExecuteAsync(req, _payConfig.WeChatPayOption);
				// 将参数(parameter)给 公众号前端  https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml
				result.Data.Result = JsonSerializer.Serialize(parameter);
			}
		}

		/// <summary>
		/// V3移动端网页支付
		/// </summary>
		private async Task WechatPayV3MobileWebAsync(PayRequestDto payReq, LayuiResultDto<PayResponseDto> result)
		{
			var model = new WeChatPayTransactionsH5BodyModel
			{
				AppId = _payConfig.AppId,
				MchId = _payConfig.WeChatPayOption.MchId,
				OutTradeNo = payReq.OutTradeNo,
				Description = payReq.Description,
				Amount = new Amount { Total = (int)(payReq.Amount * 100), Currency = "CNY" },
				Attach = payReq.Attach,
				NotifyUrl = payReq.NotifyUrl,
				SceneInfo = new SceneInfo { PayerClientIp = payReq.SpBillCreateIp, H5Info = new H5Info { Type = "Wap" } }
			};
			var request = new WeChatPayTransactionsH5Request();
			request.SetBodyModel(model);
			var rep = await _weChatPayV3Client.ExecuteAsync(request, _payConfig.WeChatPayOption);
			if (rep.IsError)
			{
				result.Code = 10000;
				result.Msg = $"{rep.Message}|{rep.Detail}";
			}
			else
				result.Data.Result = rep.H5Url;
		}

		/// <summary>
		/// V3移动应用APP支付
		/// </summary>
		private async Task WechatPayV3AppAsync(PayRequestDto payReq, LayuiResultDto<PayResponseDto> result)
		{
			var model = new WeChatPayTransactionsAppBodyModel
			{
				AppId = _payConfig.AppId,
				MchId = _payConfig.WeChatPayOption.MchId,
				OutTradeNo = payReq.OutTradeNo,
				Description = payReq.Description,
				Amount = new Amount { Total = (int)(payReq.Amount * 100), Currency = "CNY" },
				Attach = payReq.Attach,
				NotifyUrl = payReq.NotifyUrl
			};
			var request = new WeChatPayTransactionsAppRequest();
			request.SetBodyModel(model);
			var rep = await _weChatPayV3Client.ExecuteAsync(request, _payConfig.WeChatPayOption);
			if (rep.IsError)
			{
				result.Code = 10000;
				result.Msg = $"{rep.Message}|{rep.Detail}";
			}
			else
			{
				var req = new WeChatPayAppSdkRequest
				{
					PrepayId = rep.PrepayId
				};
				var parameter = await _weChatPayV3Client.ExecuteAsync(req, _payConfig.WeChatPayOption);
				// 将参数(parameter)给 ios/android端  https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_4.shtml
				result.Data.Result = JsonSerializer.Serialize(parameter);
			}
		}

        /// <summary>
        /// V3退款
        /// </summary>
        private async Task WechatPayV3RefundAsync(RefundRequestDto refundReq, LayuiResultDto<RefundResponseDto> result)
        {
			var model = new WeChatPayRefundDomesticRefundsBodyModel
			{
				OutRefundNo = refundReq.RefundNo,
				OutTradeNo = refundReq.OutTradeNo,
				Amount = new RefundAmount { Refund = (int)(refundReq.RefundAmount * 100), Total = (int)(refundReq.Total * 100), Currency = "CNY" },
				NotifyUrl = refundReq.NotifyUrl,
				Reason = refundReq.Reason
			};
            var request = new WeChatPayRefundDomesticRefundsRequest();
            request.SetBodyModel(model);
            var rep = await _weChatPayV3Client.ExecuteAsync(request, _payConfig.WeChatPayOption);
            if (rep.IsError)
            {
                result.Code = 10000;
                result.Msg = $"{rep.Message}|{rep.Detail}";
            }
            else
                result.Data.Result = rep.Body;
        }
    }
}
